package EnvReplicator ; 

use strict ; use warnings ; use Exporter; use File::Copy ; use File::Find ; 
use Configurator ; use Logger ;  

use lib '.' ; use strict ; use warnings ; 
my @ISA = qw(AutoLoader Exporter);
my @EXPORT = qw(Replicate);


#	anonymous hash !!!
our ( $confHolder , $objLogger , $objFileHandler , $MyBareName )= () ; 


BEGIN { 	

	my ( $MyBareName  , $LibDir , $RunDir ) = () ; 
	$RunDir = '' ; 
	$0 =~ m/^(.*)(\\|\/)(.*)\.([a-z]*)/; 
	$RunDir = $1 if defined $1 ; 
	push ( @INC , $RunDir) ; 	
	#debug print join ( ' ' , @INC ) ; 

} #eof sub


#STOP setting vars 

# ===============================================================
# START OO


# the constructor 
sub new	{
	my $self = shift;
	#get the has containing all the settings
	$confHolder = ${ shift @_ } ; 											
	
	return bless({}, $self);
} #eof new 




sub AUTOLOAD {
	
	my $self = shift ; 
		no strict 'refs'; 
    my $name = our $AUTOLOAD;
    *$AUTOLOAD = sub { 
		my $msg = "BOOM! BOOM! BOOM! \n RunTime Error !!!\nUndefined Function $name(@_)\n" ;
		print STDERR "$self , $msg";
    };
    goto &$AUTOLOAD;    # Restart the new routine.
}	


sub DESTROY {
	my $self = shift;
	#debug print "the DESTRUCTOR is called  \n" ; 
	return ; 
} 

# STOP OO
# =============================================================================


sub Replicate {
	
	Initialize () ; 
	
	$objLogger->LogMsg	(	"EnvReplicator::main START" ) ; 	
	my $SourceProductVersionDir = $confHolder->{'SourceProductVersionDir'} ; 
	ApplyChangesRecursively( $SourceProductVersionDir );


	$objLogger->LogMsg	(	"EnvReplicator::main STOP \n\n" ) ; 
	
	

} #eof main 


sub Initialize {

	$objLogger = new Logger (\$confHolder) ; 
	$objFileHandler = new FileHandler (\$confHolder)  ; 

} #eof sub




sub ApplyChangesRecursively	{

my $DirToRead = shift ; 
print STDERR "EnvReplicator, cannot ApplyChangesRecursively"  
unless  (defined($DirToRead));


$objLogger->LogDebugMsg ( "\$DirToRead is $DirToRead " ) ; 
my @FilesToRun = ();


find( sub { push @FilesToRun, $File::Find::name }, $DirToRead) ;

foreach my $FileToProcess ( @FilesToRun  ) 
{
		$objLogger->LogDebugMsg ( "\$FileToProcess is $FileToProcess" ) ; 
		my $FilePathSource = $FileToProcess ;  
		$objLogger->LogDebugMsg ( "\$FilePathSource is $FilePathSource" ) ; 
		my $FilePathTarget = $FilePathSource ; 

		$FilePathTarget =~ s/$confHolder->{'SourceProductName'}/$confHolder->{'TargetProductName'}/g ; 
		$FilePathTarget =~ s/$confHolder->{'SourceProductVersion'}/$confHolder->{'TargetProductVersion'}/g ; 
		$FilePathTarget =~ s/$confHolder->{'SourceProductType'}/$confHolder->{'TargetProductType'}/g ; 
		$FilePathTarget =~ s/$confHolder->{'SourceProductOwner'}/$confHolder->{'TargetProductOwner'}/g ; 
		$FilePathTarget =~ s/$confHolder->{'SourceProductBaseDir'}/$confHolder->{'TargetProductBaseDir'}/g ; 		

		$FilePathTarget =~ s/$confHolder->{'SourceEnvironmentName'}/$confHolder->{'TargetEnvironmentName'}/g ; 


		$objLogger->LogDebugMsg ( "\$FilePathTarget is $FilePathTarget" ) ; 

		if (-d $FilePathSource )	{ 
		
			$objFileHandler->MkDir($FilePathTarget); 
			$objLogger->LogDebugMsg ( "found dir create the \$FilePathTarget $FilePathTarget" ) ; 
		}
		else 	{	
		
			copy ( $FilePathSource , $FilePathTarget ) ; 
			$objLogger->LogDebugMsg ( "found FILE copy the \$FilePathTarget $FilePathTarget" ) ; 
			ReplaceConfValuesInFile ( $FilePathTarget ) ; 
			$objLogger->LogDebugMsg ( "Replaced the values of \$FilePathTarget $FilePathTarget" ) ; 

		}


} #eof foreach 



} #eof sub



sub ReplaceConfValuesInFile {

my $FileWithReplaceValues = shift ; 


# handle only the ini , sh and cmd files
return  unless ( $FileWithReplaceValues =~ m/^(.*)[ini|sh|cmd|txt]$/ ) ; 

$objLogger->LogDebugMsg ( "\$FileWithReplaceValues is $FileWithReplaceValues " ) ; 

my $StrFileWithReplaceValues = $objFileHandler->ReadFileReturnString( $FileWithReplaceValues ) ; 


$StrFileWithReplaceValues =~ s/$confHolder->{'SourceProductName'}/$confHolder->{'TargetProductName'}/g ; 
$StrFileWithReplaceValues =~ s/$confHolder->{'SourceProductVersion'}/$confHolder->{'TargetProductVersion'}/g ; 
$StrFileWithReplaceValues =~ s/$confHolder->{'SourceProductType'}/$confHolder->{'TargetProductType'}/g ; 
$StrFileWithReplaceValues =~ s/$confHolder->{'SourceProductOwner'}/$confHolder->{'TargetProductOwner'}/g ; 
$StrFileWithReplaceValues =~ s/$confHolder->{'SourceProductBaseDir'}/$confHolder->{'TargetProductBaseDir'}/g ; 		

$objFileHandler->PrintToFile( $FileWithReplaceValues , $StrFileWithReplaceValues ) ; 

} #eof sub




1 ; 

__END__



=head1 NAME

EnvReplicator

=head1 SYNOPSIS

use EnvReplicator; 
  

=head1 DESCRIPTION

This package reads recursively a predifined directory 
and changes predifined source to target values


=head2 EXPORT


=head1 SEE ALSO

perldoc perlvars

No mailing list for this module


=head1 AUTHOR

yordan.georgiev@gmail.com

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2011 Yordan Georgiev

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.1 or,
at your option, any later version of Perl 5 you may have available.



VersionHistory: 
0.0.2 --- ysg --- Integrated into morphus 
0.0.1 --- ysg --- Initial creation as a separate tool 

TODO:
specify better search and replace criteria ... dev , test , qa are not ..

=cut

